package cn.com.anypay.manager.service.impl;

import cn.com.anypay.manager.service.MapService;
import cn.com.anysdk.map.config.BaiduMapConfig;
import cn.com.anysdk.map.config.MapConfig;
import cn.com.anysdk.map.config.MockConfig;
import cn.com.anysdk.map.factory.MapServiceFactory;
import cn.com.anysdk.map.model.*;
import cn.com.anysdk.map.model.MapProviderType;
import cn.com.anysdk.map.exception.MapException;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import java.util.Map;

@Slf4j
@Service
public class MapServiceImpl implements MapService {

    private MapConfig currentConfig;
    private cn.com.anysdk.map.service.MapService currentMapService;

    @Override
    public String switchProvider(Map<String, Object> config) throws MapException {
        log.info("开始切换地图服务商，配置参数: {}", config);
        try {
            // 创建新的地图配置
            MapConfig newConfig = createMapConfigFromMap(config);
            log.debug("创建地图配置成功: {}", newConfig);

            // 更新当前配置
            currentConfig = newConfig;

            // 创建新的地图服务实例
            currentMapService = MapServiceFactory.createMapService(newConfig);
            log.info("地图服务实例创建成功，类型: {}", newConfig.getType());

            return "Successfully switched to " + newConfig.getType() + " map provider";
        } catch (Exception e) {
            log.error("切换地图服务商失败: {}", e.getMessage(), e);
            throw new MapException("Failed to switch map provider: " + e.getMessage(), e);
        }
    }

    @Override
    public LocationResult geocode(String address) throws MapException {
        log.debug("开始地址解析，地址: {}", address);
        if (currentMapService == null) {
            log.error("地图服务未初始化");
            throw new MapException("Map provider not initialized. Please call switchProvider first.");
        }
        try {
            LocationResult result = currentMapService.geocode(address);
            log.debug("地址解析成功，结果: {}", result);
            return result;
        } catch (Exception e) {
            log.error("地址解析失败，地址: {}, 错误: {}", address, e.getMessage(), e);
            throw new MapException("Geocoding failed: " + e.getMessage(), e);
        }
    }

    @Override
    public AddressResult reverseGeocode(Location location) throws MapException {
        log.debug("开始逆地址解析，坐标: {}", location);
        if (currentMapService == null) {
            log.error("地图服务未初始化");
            throw new MapException("Map provider not initialized. Please call switchProvider first.");
        }
        try {
            AddressResult result = currentMapService.reverseGeocode(location);
            log.debug("逆地址解析成功，结果: {}", result);
            return result;
        } catch (Exception e) {
            log.error("逆地址解析失败，坐标: {}, 错误: {}", location, e.getMessage(), e);
            throw new MapException("Reverse geocoding failed: " + e.getMessage(), e);
        }
    }

    @Override
    public LocationResult convertCoordinate(Location location, CoordinateType fromType, CoordinateType toType) throws MapException {
        log.debug("开始坐标转换，原坐标: {}，源坐标系: {}，目标坐标系: {}", location, fromType, toType);
        if (currentMapService == null) {
            log.error("地图服务未初始化");
            throw new MapException("Map provider not initialized. Please call switchProvider first.");
        }
        try {
            LocationResult result = currentMapService.convertCoordinate(location, fromType, toType);
            log.debug("坐标转换成功，结果: {}", result);
            return result;
        } catch (Exception e) {
            log.error("坐标转换失败，原坐标: {}，源坐标系: {}，目标坐标系: {}，错误: {}", 
                    location, fromType, toType, e.getMessage(), e);
            throw new MapException("Coordinate conversion failed: " + e.getMessage(), e);
        }
    }

    private MapConfig createMapConfigFromMap(Map<String, Object> config) {
        String typeStr = (String) config.get("type");
        if (typeStr == null) {
            log.error("缺少地图服务商类型参数");
            throw new IllegalArgumentException("Map provider type is required");
        }

        MapProviderType type = MapProviderType.valueOf(typeStr.toUpperCase());
        log.debug("创建地图配置，类型: {}", type);

        return switch (type) {
            case BAIDU -> {
                BaiduMapConfig baiduConfig = new BaiduMapConfig();
                baiduConfig.setType(MapProviderType.BAIDU);
                baiduConfig.setAk((String) config.get("ak"));
                log.debug("创建百度地图配置: {}", baiduConfig);
                yield baiduConfig;
            }
            case MOCK -> {
                MockConfig mockConfig = new MockConfig();
                mockConfig.setType(MapProviderType.MOCK);
                log.debug("创建模拟地图配置: {}", mockConfig);
                yield mockConfig;
            }
            default -> {
                log.error("不支持的地图服务商类型: {}", type);
                throw new IllegalArgumentException("Unsupported map provider type: " + type);
            }
        };
    }
}
